package com.knowledgegraph.neo4j.repository;

import com.knowledgegraph.neo4j.entity.GraphEntity;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * Neo4j 实体仓库
 */
@Repository
public interface GraphEntityRepository extends Neo4jRepository<GraphEntity, Long> {
    
    /**
     * 根据知识图谱ID查询实体
     */
    List<GraphEntity> findByGraphId(Long graphId);
    
    /**
     * 根据类型查询实体
     */
    List<GraphEntity> findByType(String type);
    
    /**
     * 根据名称模糊查询实体
     */
    List<GraphEntity> findByNameContaining(String name);
    
    /**
     * 根据知识图谱ID和类型查询实体
     */
    List<GraphEntity> findByGraphIdAndType(Long graphId, String type);
    
    /**
     * 统计各类型实体数量
     */
    @Query("MATCH (e:Entity) WHERE e.graphId = $graphId RETURN e.type as type, count(e) as count")
    List<Map<String, Object>> countEntitiesByType(@Param("graphId") Long graphId);
    
    /**
     * 查询实体及其关系
     */
    @Query("MATCH (e:Entity)-[r]-(related:Entity) WHERE e.id = $entityId RETURN e, r, related")
    List<Map<String, Object>> findEntityWithRelations(@Param("entityId") Long entityId);
    
    /**
     * 查询知识图谱的所有实体和关系
     */
    @Query("MATCH (e:Entity)-[r]-(related:Entity) WHERE e.graphId = $graphId AND related.graphId = $graphId RETURN e, r, related")
    List<Map<String, Object>> findGraphStructure(@Param("graphId") Long graphId);
    
    /**
     * 查询实体的邻居节点
     */
    @Query("MATCH (e:Entity)-[r]-(neighbor:Entity) WHERE e.id = $entityId RETURN neighbor, r")
    List<Map<String, Object>> findNeighbors(@Param("entityId") Long entityId);
    
    /**
     * 查询两个实体之间的最短路径
     */
    @Query("MATCH path = shortestPath((start:Entity)-[*]-(end:Entity)) " +
           "WHERE start.id = $startId AND end.id = $endId " +
           "RETURN path")
    List<Map<String, Object>> findShortestPath(@Param("startId") Long startId, @Param("endId") Long endId);
    
    /**
     * 根据度数查询重要实体
     */
    @Query("MATCH (e:Entity)-[r]-() WHERE e.graphId = $graphId " +
           "WITH e, count(r) as degree " +
           "ORDER BY degree DESC " +
           "LIMIT $limit " +
           "RETURN e, degree")
    List<Map<String, Object>> findImportantEntities(@Param("graphId") Long graphId, @Param("limit") Integer limit);
    
    /**
     * 全文搜索实体
     */
    @Query("MATCH (e:Entity) WHERE e.graphId = $graphId AND " +
           "(e.name CONTAINS $keyword OR e.description CONTAINS $keyword) " +
           "RETURN e ORDER BY e.name")
    List<GraphEntity> searchEntities(@Param("graphId") Long graphId, @Param("keyword") String keyword);
}